﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SharePhone.Query
{
    public class CamlQuery
    {
        #region Scope enum

        public enum Scope
        {
            SiteCollection,
            Recursive,
            CurrentFolderOnly
        } ;

        #endregion

        public int RowLimit;

        private CamlExpression exp;
        private Dictionary<string, bool> ordering;
        private Scope scope;
        private List<string> viewFields;

        /// <summary>
        /// Returns the resulting CAML query string.
        /// </summary>
        public string Query
        {
            get { return BuildQuery(); }
        }


        /// <summary>
        /// Add a field to order the query result by
        /// </summary>
        /// <param name="fieldRef"></param>
        public void AddOrdering(string fieldRef)
        {
            AddOrdering(fieldRef, true);
        }

        public void AddOrdering(string fieldRef, bool ascending)
        {
            if (ordering == null)
                ordering = new Dictionary<string, bool>();
            ordering.Add(fieldRef, ascending);
        }

        /// <summary>
        /// Sets the scope of the query 
        /// </summary>
        /// <param name="scope"></param>
        public void SetScope(Scope scope)
        {
            this.scope = scope;
        }

        /// <summary>
        /// Adds the specified field to the view fields.
        /// </summary>
        /// <param name="name"></param>
        public void AddViewField(string name)
        {
            viewFields.Add(name);
        }

        private string BuildQuery()
        {
            return BuildQuery(exp, ordering, scope, viewFields);
        }

        public static string BuildQuery(CamlExpression exp, Dictionary<string, bool> ordering, Scope scope,
                                        List<string> viewFields)
        {
            var sb = new StringBuilder();
            sb.Append("<Where>");
            sb.Append(exp.Query);
            if (sb.ToString().Length < 8)
                return string.Empty;
            sb.Append("</Where>");
            if (ordering != null && ordering.Count > 0)
            {
                sb.Append("<OrderBy>");
                foreach (string order in ordering.Keys)
                {
                    sb.Append(string.Format("<FieldRef Name='{0}' Ascending='{1}'/>", order,
                                            ordering[order].ToString().ToUpper()));
                }
                sb.Append("</OrderBy>");
            }
            if (viewFields != null)
            {
                sb.Append(String.Format("<ViewFields {0}>", ((scope == Scope.Recursive) ? "Scope='Recursive'" : "")));
                foreach (string field in viewFields)
                {
                    sb.Append(String.Format("<FieldRef Name='{0}'/>", field));
                }
                sb.Append("</ViewFields>");
            }
            return sb.ToString();
        }
    }
}